/**
 * 
 */
package com.bbva.kyfb.kyfbdaofcimpl;

import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.commons.lang.StringUtils;
import org.springframework.transaction.annotation.Transactional;

import com.bbva.kyfb.kyfbdto.firmas.filtros.FiltroFicheros;
import com.bbva.kyfb.kyfbjpatlbh.dominiotlbh.Ttlsbfua;
import com.bbva.kyfb.kyfbutils.constantes.ConstantesFO;
import com.bbva.kyfb.kyfbutils.constantes.UtilFO;
import com.bbva.kyfb.kyfbutils.dao.DaoUtils;

/**
 * The Class ServicioDaoImpl.
 *
 * @author xe20973
 */
public class ServicioDaoImpl {

	/** The em. */
	@PersistenceContext(unitName="persistenceUnitTLBH")
	private transient EntityManager em;

	/** The emTLSB. */
	@PersistenceContext(unitName="persistenceUnitTLSB")
	private transient EntityManager emTLSB;
		
	/**
	 * Gets the em.
	 *
	 * @return the em
	 */
	public EntityManager getEm() {
		return em;
	}

	/**
	 * Find auditoria componente.
	 *
	 * @param codClienteCash the cod cliente cash
	 * @param claseOrden the clase orden
	 * @param idOrden the id orden
	 * @param estados the estados
	 * @param estadosFijos the estados fijos
	 * @return the list
	 */
	@SuppressWarnings("unchecked")
	@Transactional(value="tlbh")
	protected List<Ttlsbfua> findAuditoriaComponente(final String codClienteCash, final String claseOrden, final String idOrden, final String[] estados, final String[] estadosFijos) {

		final Map<Integer, Object> paramValues = new HashMap<Integer, Object>();
		final StringBuilder filteredQuery = new StringBuilder("SELECT F.* FROM TLSB.TTLSBFUA F LEFT JOIN TLSB.TTLSBACU A ON F.COD_ACCION = A.COD_ACCION ");
		filteredQuery.append(DaoUtils.addFilter("F.COD_CLIECASH", "=", codClienteCash, paramValues, null, null));
		filteredQuery.append(DaoUtils.addFilter("F.COD_CLASEORD", "=", claseOrden, paramValues, true, null));
		filteredQuery.append(DaoUtils.addFilter("F.COD_IDORDEN", "=", idOrden, paramValues, true, null));
		filteredQuery.append(DaoUtils.addInClause("F.COD_ESTADFIC", estadosFijos, paramValues, true, null));
		filteredQuery.append(DaoUtils.addInClause("F.COD_ESTADFIC", estados, paramValues, true, null));

		//Orden (Por defecto ordenado por F._AUD_MODIFIC (fecha) y F.FEC_ACCION2 (minutos))
		final String ordParams[]={UtilFO.getCampoOrden(null, ConstantesFO.PET_AUDITORIA),null};
		filteredQuery.append(DaoUtils.addOrderSimple(ordParams));

		final Query q=em.createNativeQuery(filteredQuery.toString(),Ttlsbfua.class);
		DaoUtils.addQueryParams(paramValues, q);

		final List<Ttlsbfua> resultados= q.getResultList();

		DaoUtils.atLeastOneRecord(resultados);

		return resultados;
	}

	/**
	 * Find referencia.
	 *
	 * @param codClienteCash the cod cliente cash
	 * @param filtro the filtro
	 * @param ordenante the ordenante
	 * @param estadosFijos the estados fijos
	 * @return the list
	 */
	@SuppressWarnings("unchecked")
	@Transactional(value="tlbh")
	protected List<Object[]> findReferencia(final String codClienteCash, final FiltroFicheros filtro, final boolean ordenante, final String[] estadosFijos, Long[] numItems, boolean esConfeccion) {

		final Map<Integer, Object> paramValues = new HashMap<Integer, Object>();
		StringBuilder filteredQuery = null;

		if (esConfeccion) {
			filteredQuery = new StringBuilder(getQueryBaseConfeccion(codClienteCash,filtro,ordenante,estadosFijos,paramValues));
			
			//Paginacion y ordenacion solo para confeccion
			if (filtro != null && !StringUtils.isEmpty(filtro.getOrdenarPor())) {	
				//Paginacion si procede (Por defecto desde 0 hasta 0) con orden si procede (Por defecto ordenado por TIM_FICHERO (Fecha de creacion))
				if(filtro.getPaginarDesde()>=0 && filtro.getNumElementos()>0) {
					Object pagParams[]={filtro.getPaginarDesde(),filtro.getNumElementos(),	//2 primeros son parametros normales
							filtro.getOrdenarPor(),filtro.getModoOrdenacion()}; //2 segundos son para concatenar directamente
					
					filteredQuery=DaoUtils.addPaginate(filteredQuery,pagParams, paramValues);
				}else{									
					//Orden si procede (Por defecto ordenado por TIM_FICHERO (Fecha de creacion))
					String ordParams[]={filtro.getOrdenarPor(),filtro.getModoOrdenacion()};				
					filteredQuery.append(DaoUtils.addOrderSimple(ordParams));
				}
			}
			
		} else { //Paginacion y ordenacion de historico se realiza despues de cruzar con query
			filteredQuery = new StringBuilder(getQueryBaseHistorico(codClienteCash,filtro,ordenante,estadosFijos,numItems,paramValues));
		}

		final Query q= em.createNativeQuery(filteredQuery.toString());
		DaoUtils.addQueryParams(paramValues, q);

		final List<Object[]> resultados= q.getResultList();

		if (esConfeccion){
			DaoUtils.atLeastOneRecord(resultados);
		}

		return resultados;
	}
	
	/**
	 * Find referencia estados intermedios.
	 *
	 * @param codClienteCash the cod cliente cash
	 * @param filtro the filtro
	 * @param ordenante the ordenante
	 * @param estadosFijos the estados fijos
	 * @return the list
	 */
	@SuppressWarnings("unchecked")
	@Transactional(value="tlsb")
	protected List<Object[]> findReferenciaEstadosIntermedios(final String codClienteCash, final FiltroFicheros filtro, final boolean ordenante, boolean esConfeccion) {

		Map<Integer, Object> paramValues = new HashMap<Integer, Object>();
		StringBuilder filteredQueryEstadosIntermedios = null;
		
			filteredQueryEstadosIntermedios = new StringBuilder(getQueryBaseEstadosIntermedios(codClienteCash,filtro,ordenante,paramValues));
		
		Query q= emTLSB.createNativeQuery(filteredQueryEstadosIntermedios.toString());
		DaoUtils.addQueryParams(paramValues, q);
		
		List<Object[]> resultados= q.getResultList();

		return resultados;
	}

	/**
	 * Gets the query base.
	 *
	 * @param codClienteCash the cod cliente cash
	 * @param filtro the filtro
	 * @param ordenante the ordenante
	 * @param estadosFijos the estados fijos
	 * @param paramValues the param values
	 * @return the query base
	 */
	private String getQueryBase(final String codClienteCash, final FiltroFicheros filtro, final boolean ordenante, final String[] estadosFijos, final Map<Integer, Object> paramValues){

		final StringBuilder filteredQuery = new StringBuilder("SELECT DISTINCT ");

		filteredQuery.append("VARCHAR(C.DES_NOMFICH) AS DES_NOMFICH, VARCHAR(C.FEC_PROCESCA) AS FEC_PROCESCA, C.QNU_TOTREGIS AS QNU_TOTREGIS, C.QTY_TOTIMP AS QTY_TOTIMP, ");
		filteredQuery.append("VARCHAR(C.COD_ESTACASH) AS COD_ESTACASH, VARCHAR(C.COD_CLASEORD) AS COD_CLASEORD, VARCHAR(C.COD_IDORDEN) AS COD_IDORDEN, VARCHAR(O.DES_CUENORIG) AS DES_CUENORIG, ");
		filteredQuery.append("VARCHAR(D.COD_ABREVIAT) AS COD_ABREVIAT, VARCHAR(CLO.XTI_MODOORDE) AS XTI_MODOORDE, S.TIM_FICHERO AS TIM_FICHERO ");
		filteredQuery.append("FROM TLSB.TTLSBCAB C LEFT OUTER JOIN TLSB.TTLSBCOR O ON (O.COD_CLIECASH = C.COD_CLIECASH ");
		filteredQuery.append("AND O.COD_CLASEORD = C.COD_CLASEORD ");
		filteredQuery.append("AND O.COD_IDORDEN = C.COD_IDORDEN) ");
		filteredQuery.append("INNER JOIN TLSB.TTLSBDIV D ON (C.COD_DIISOALF = D.COD_DIISOALF OR C.COD_DIISOALF = D.COD_ABREVIAT) ");
		filteredQuery.append("INNER JOIN TLSB.TTLSBCLO CLO ON (CLO.COD_CLASEORD = C.COD_CLASEORD) ");

		if(ordenante) {
			filteredQuery.append("INNER JOIN TLSB.TTLSBFUA F ON (F.COD_CLIECASH = C.COD_CLIECASH ");
			filteredQuery.append("AND F.COD_CLASEORD = C.COD_CLASEORD AND F.COD_IDORDEN = C.COD_IDORDEN) ");
		}

		// Completamos con el LEFT JOIN
		filteredQuery.append("LEFT OUTER JOIN TLSB.TTLSBSFO S ON (S.COD_CLIECASH = C.COD_CLIECASH AND S.COD_CLASEORD = C.COD_CLASEORD AND C.COD_IDORDEN = S.COD_IDORDEN) ");

		filteredQuery.append(DaoUtils.addFilter("C.COD_CLIECASH", "=", codClienteCash, paramValues, null, null));
		filteredQuery.append(DaoUtils.addInClause("C.COD_ESTACASH", estadosFijos, paramValues, true, null));
		filteredQuery.append(DaoUtils.addFilter("C.QNU_TOTREGIS", ">", 0, paramValues, true, null));

		if (filtro != null) {
			filteredQuery.append(DaoUtils.addFilter("S.TIM_FICHERO", ">=", filtro.getFechaCreacionDesde(), paramValues, true, null));
			filteredQuery.append(DaoUtils.addFilter("S.TIM_FICHERO", "<", UtilFO.addOrsubtractsDate(filtro.getFechaCreacionHasta(), 1), paramValues, true, null));
			filteredQuery.append(DaoUtils.addFilter("C.FEC_PROCESCA", ">=", filtro.getFechaProcesoDesde(), paramValues, true, new SimpleDateFormat("yyyyMMdd")));
			filteredQuery.append(DaoUtils.addFilter("C.FEC_PROCESCA", "<=", filtro.getFechaProcesoHasta(), paramValues, true, new SimpleDateFormat("yyyyMMdd")));
			filteredQuery.append(DaoUtils.addInClause("C.COD_CLASEORD", filtro.getClaseOrden(), paramValues, true, null));
			filteredQuery.append(DaoUtils.addFilter("F.COD_USUARIO", "=", filtro.getCodUsuario(), paramValues, true, null));
			filteredQuery.append(DaoUtils.addFilter("C.QTY_TOTIMP", ">=", filtro.getImporteDesde(), paramValues, true, null));
			filteredQuery.append(DaoUtils.addFilter("C.QTY_TOTIMP", "<=", filtro.getImporteHasta(), paramValues, true, null));
			filteredQuery.append(DaoUtils.addInClause("D.COD_ABREVIAT", filtro.getDivisas(), paramValues, true, null));
			filteredQuery.append(DaoUtils.addInClause("C.COD_ESTACASH", filtro.getEstados(), paramValues, true, null));
			filteredQuery.append(DaoUtils.addFilter("C.COD_IDORDEN", "=", filtro.getIdOrden(), paramValues, true, null));
		}
		return filteredQuery.toString();
	}

	/**
	 * Gets the query base Estados intermedios.
	 *
	 * @param codClienteCash the cod cliente cash
	 * @param filtro the filtro
	 * @param ordenante the ordenante
	 * @param paramValues the param values
	 * @return the query base
	 */
	private String getQueryBaseEstadosIntermedios(final String codClienteCash, final FiltroFicheros filtro, final boolean ordenante, final Map<Integer, Object> paramValues){
			
		StringBuilder filteredQuery = new StringBuilder("SELECT DISTINCT ");
		
			filteredQuery.append("B.QNU_NUMITEM AS QNU_NUMITEM, B.COD_LOGONAPL AS COD_LOGONAPL, B.FEC_RECEPCIO AS FEC_RECEPCIO,");
			filteredQuery.append("I.DES_NOMBRE AS DES_NOMBRE, I.COD_COMREFEX AS COD_COMREFEX ");
			filteredQuery.append("FROM BDBZ.TBDBZBIT B INNER JOIN BDBZ.TBDBZITE I ON (B.QNU_NUMITEM = I.QNU_NUMITEM)");
			
		String pathBuzon="%"+ConstantesFO.BUZON_DEFECTO+
						 "%"+codClienteCash.substring(0,4)+
						 "%"+codClienteCash.charAt(codClienteCash.length()-3)+
						 "%"+codClienteCash.substring(codClienteCash.length()-2)+
						 "%"+codClienteCash+
						 "%";
			
			filteredQuery.append(DaoUtils.addFilter("I.DES_PATH", "LIKE", pathBuzon, paramValues, null, null));
			filteredQuery.append("AND ((B.COD_LOGONAPL = 'ORDENESCRC') OR (B.COD_LOGONAPL = 'ORDENESCSB' AND B.XTI_BUZON = 'A') OR (B.COD_LOGONAPL='ORDENESCRC_MOVIDO')) ");						
			filteredQuery.append(DaoUtils.addFilterFuncionSQL(true, "B.FEC_RECEPCIO","=","CURRENT DATE"));
			
		//filteredQuery.append(DaoUtils.addFilter("I.COD_COMREFEX", "=", tipoFichero, paramValues, true, null));		
		//filteredQuery.append("ORDER BY B.QNU_NUMITEM");
		
		return filteredQuery.toString();
	}	
	
	/**
	 * Gets the query base.
	 *
	 * @param codClienteCash the cod cliente cash
	 * @param filtro the filtro
	 * @param ordenante the ordenante
	 * @param estadosFijos the estados fijos
	 * @param paramValues the param values
	 * @return the query base
	 */
	private String getQueryBaseHistorico(final String codClienteCash, final FiltroFicheros filtro, final boolean ordenante, final String[] estadosFijos, final Long[] numItems, final Map<Integer, Object> paramValues){

		StringBuilder filteredQuery = new StringBuilder("SELECT DISTINCT ");
		
		filteredQuery.append("VARCHAR(C.DES_NOMFICH) AS DES_NOMFICH, VARCHAR(C.FEC_PROCESCA) AS FEC_PROCESCA, C.QNU_TOTREGIS AS QNU_TOTREGIS, C.QTY_TOTIMP AS QTY_TOTIMP, ");  
		filteredQuery.append("VARCHAR(C.COD_ESTACASH) AS COD_ESTACASH, VARCHAR(C.COD_CLASEORD) AS COD_CLASEORD, VARCHAR(C.COD_IDORDEN) AS COD_IDORDEN, VARCHAR(O.DES_CUENORIG) AS DES_CUENORIG, ");
		filteredQuery.append("VARCHAR(D.COD_ABREVIAT) AS COD_ABREVIAT, VARCHAR(CLO.XTI_MODOORDE) AS XTI_MODOORDE, S.TIM_FICHERO AS TIM_FICHERO ");
		filteredQuery.append("FROM TLSB.TTLSBCAB C LEFT OUTER JOIN TLSB.TTLSBCOR O ON (O.COD_CLIECASH = C.COD_CLIECASH ");
		filteredQuery.append("AND O.COD_CLASEORD = C.COD_CLASEORD "); 
		filteredQuery.append("AND O.COD_IDORDEN = C.COD_IDORDEN) ");
		filteredQuery.append("INNER JOIN TLSB.TTLSBDIV D ON (C.COD_DIISOALF = D.COD_DIISOALF OR C.COD_DIISOALF = D.COD_ABREVIAT) ");
		filteredQuery.append("INNER JOIN TLSB.TTLSBCLO CLO ON (CLO.COD_CLASEORD = C.COD_CLASEORD) ");
		
		if(ordenante) {
			filteredQuery.append("INNER JOIN TLSB.TTLSBFUA F ON (F.COD_CLIECASH = C.COD_CLIECASH ");
			filteredQuery.append("AND F.COD_CLASEORD = C.COD_CLASEORD AND F.COD_IDORDEN = C.COD_IDORDEN) ");
		}
		
		// Completamos con el LEFT JOIN
		filteredQuery.append("LEFT OUTER JOIN TLSB.TTLSBSFO S ON (C.COD_IDORDEN = S.COD_IDORDEN) ");
		
		filteredQuery.append(DaoUtils.addFilter("C.COD_CLIECASH", "=", codClienteCash, paramValues, null, null));
		
		//Se obtienen los ficheros sin estado HO y las ordenes para cualquier estado fijo
		if(numItems!=null && numItems.length>0){
			filteredQuery.append(DaoUtils.addInClause("S.QNU_NUMITEM", numItems, paramValues, true, null));			
			
		}
		filteredQuery.append(" AND ((CLO.XTI_MODOORDE = 'F' AND S.COD_ESTADODS IN ('EN','RE','EL','BM','BD','PE')) OR (CLO.XTI_MODOORDE = 'O'   AND S.COD_ESTADODS IN ('EN','RE','EL','BM','BD','PE', 'HO')))");
		//filteredQuery.append(DaoUtils.addInClause("S.COD_ESTADODS", estadosFijos, paramValues, true, null));
		
		if(numItems!=null && numItems.length>0){
			filteredQuery.append(") ");
		}		
					
		if (filtro != null) {
			filteredQuery.append(DaoUtils.addFilter("S.TIM_FICHERO", ">=", filtro.getFechaCreacionDesde(), paramValues, true, null));
			filteredQuery.append(DaoUtils.addFilter("S.TIM_FICHERO", "<=", filtro.getFechaCreacionHasta(), paramValues, true, null));
			filteredQuery.append(DaoUtils.addFilter("C.FEC_PROCESCA", ">=", filtro.getFechaProcesoDesde(), paramValues, true, new SimpleDateFormat("yyyyMMdd")));
			filteredQuery.append(DaoUtils.addFilter("C.FEC_PROCESCA", "<=", filtro.getFechaProcesoHasta(), paramValues, true, new SimpleDateFormat("yyyyMMdd")));
			filteredQuery.append(DaoUtils.addInClause("C.COD_CLASEORD", filtro.getClaseOrden(), paramValues, true, null));
			filteredQuery.append(DaoUtils.addFilter("F.COD_USUARIO", "=", filtro.getCodUsuario(), paramValues, true, null));
			filteredQuery.append(DaoUtils.addFilter("C.QTY_TOTIMP", ">=", filtro.getImporteDesde(), paramValues, true, null));
			filteredQuery.append(DaoUtils.addFilter("C.QTY_TOTIMP", "<=", filtro.getImporteHasta(), paramValues, true, null));
			filteredQuery.append(DaoUtils.addInClause("D.COD_ABREVIAT", filtro.getDivisas(), paramValues, true, null));
			filteredQuery.append(DaoUtils.addInClause("S.COD_ESTADODS", filtro.getEstados(), paramValues, true, null));
			filteredQuery.append(DaoUtils.addFilter("C.COD_IDORDEN", "=", filtro.getIdOrden(), paramValues, true, null));
		}	
		return filteredQuery.toString();
	}		
	
	/**
	 * Gets the query base.
	 *
	 * @param codClienteCash the cod cliente cash
	 * @param filtro the filtro
	 * @param ordenante the ordenante
	 * @param estadosFijos the estados fijos
	 * @param paramValues the param values
	 * @return the query base
	 */
	private String getQueryBaseConfeccion(final String codClienteCash, final FiltroFicheros filtro, final boolean ordenante, final String[] estadosFijos, final Map<Integer, Object> paramValues){

		final StringBuilder filteredQuery = new StringBuilder("SELECT DISTINCT ");

		filteredQuery.append("VARCHAR(C.DES_NOMFICH) AS DES_NOMFICH, VARCHAR(C.FEC_PROCESCA) AS FEC_PROCESCA, C.QNU_TOTREGIS AS QNU_TOTREGIS, C.QTY_TOTIMP AS QTY_TOTIMP, ");
		filteredQuery.append("VARCHAR(C.COD_ESTACASH) AS COD_ESTACASH, VARCHAR(C.COD_CLASEORD) AS COD_CLASEORD, VARCHAR(C.COD_IDORDEN) AS COD_IDORDEN, VARCHAR(O.DES_CUENORIG) AS DES_CUENORIG, ");
		filteredQuery.append("VARCHAR(D.COD_ABREVIAT) AS COD_ABREVIAT, VARCHAR(CLO.XTI_MODOORDE) AS XTI_MODOORDE, ");
		filteredQuery.append("VARCHAR(C.XSN_FORMPAGO) AS XSN_FORMPAGO ");
		filteredQuery.append("FROM TLSB.TTLSBCAB C LEFT OUTER JOIN TLSB.TTLSBCOR O ON (O.COD_CLIECASH = C.COD_CLIECASH ");
		filteredQuery.append("AND O.COD_CLASEORD = C.COD_CLASEORD ");
		filteredQuery.append("AND O.COD_IDORDEN = C.COD_IDORDEN) ");
		filteredQuery.append("INNER JOIN TLSB.TTLSBDIV D ON (C.COD_DIISOALF = D.COD_DIISOALF OR C.COD_DIISOALF = D.COD_ABREVIAT) ");
		filteredQuery.append("INNER JOIN TLSB.TTLSBCLO CLO ON (CLO.COD_CLASEORD = C.COD_CLASEORD) ");
		// filteredQuery.append("INNER JOIN TLSB.TTLSBCOR COR ON (C.COD_IDORDEN = COR.COD_IDORDEN AND COR.COD_CLIECASH = C.COD_CLIECASH AND COR.COD_CLASEORD = C.COD_CLASEORD) ");
		filteredQuery.append("INNER JOIN TLSB.TTLSBORI ORI on ((O.COD_CLIECASH = ORI.COD_CLIECASH AND O.COD_CDNITR = ORI.COD_CDNITR AND ");
		filteredQuery.append("O.COD_SUFPRESE = ORI.COD_SUFPRESE AND O.COD_IDORIGEN = ORI.COD_IDORIGEN AND O.COD_CLASEORD = ORI.COD_CLASEORD and C.COD_ESTACASH='001') or C.COD_ESTACASH='003' or C.COD_ESTACASH='011') ");

		if(ordenante) {
			filteredQuery.append("INNER JOIN TLSB.TTLSBFUA F ON (F.COD_CLIECASH = C.COD_CLIECASH ");
			filteredQuery.append("AND F.COD_CLASEORD = C.COD_CLASEORD AND F.COD_IDORDEN = C.COD_IDORDEN) ");
		}

		filteredQuery.append(DaoUtils.addFilter("C.COD_CLIECASH", "=", codClienteCash, paramValues, null, null));
		filteredQuery.append(DaoUtils.addFilter("C.QNU_TOTREGIS", ">", 0, paramValues, true, null));

		if (filtro != null) {
			filteredQuery.append(DaoUtils.addFilter("C.FEC_PROCESCA", ">=", filtro.getFechaProcesoDesde(), paramValues, true, new SimpleDateFormat("yyyyMMdd")));
			filteredQuery.append(DaoUtils.addFilter("C.FEC_PROCESCA", "<=", filtro.getFechaProcesoHasta(), paramValues, true, new SimpleDateFormat("yyyyMMdd")));
			filteredQuery.append(DaoUtils.addInClause("C.COD_CLASEORD", filtro.getClaseOrden(), paramValues, true, null));
			filteredQuery.append(DaoUtils.addFilter("F.COD_USUARIO", "=", filtro.getCodUsuario(), paramValues, true, null));
			filteredQuery.append(DaoUtils.addFilter("C.QTY_TOTIMP", ">=", filtro.getImporteDesde(), paramValues, true, null));
			filteredQuery.append(DaoUtils.addFilter("C.QTY_TOTIMP", "<=", filtro.getImporteHasta(), paramValues, true, null));
			filteredQuery.append(DaoUtils.addInClause("D.COD_ABREVIAT", filtro.getDivisas(), paramValues, true, null));
			filteredQuery.append(DaoUtils.addInClause("C.COD_ESTACASH", filtro.getEstados(), paramValues, true, null));
			filteredQuery.append(DaoUtils.addFilter("C.COD_IDORDEN", "=", filtro.getIdOrden(), paramValues, true, null));
		}
		return filteredQuery.toString();
	}

	/**
	 * Gets the total componentes referencia.
	 *
	 * @param codClienteCash the cod cliente cash
	 * @param filtro the filtro
	 * @param ordenante the ordenante
	 * @param estadosFijos the estados fijos
	 * @return the total componentes referencia
	 */
	@Transactional(value="tlbh")
	public int getTotalComponentesReferencia(final String codClienteCash, final FiltroFicheros filtro, final boolean ordenante, final String[] estadosFijos, final boolean esConfeccion){
		final Map<Integer, Object> paramValues = new HashMap<Integer, Object>();
		final StringBuilder filteredQueryCount = new StringBuilder("SELECT COUNT(*) AS TOTAL FROM (");

		if (esConfeccion) {
			filteredQueryCount.append(getQueryBaseConfeccion(codClienteCash,filtro,ordenante, estadosFijos,paramValues)+")");
		} else {
			filteredQueryCount.append(getQueryBase(codClienteCash,filtro,ordenante, estadosFijos,paramValues)+")");
		}

		final Query q = em.createNativeQuery(filteredQueryCount.toString());
		DaoUtils.addQueryParams(paramValues, q);

		return ((Number)q.getSingleResult()).intValue();
	}

}
